package com.cpe.service.account;

import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.commons.lang3.RandomUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.cloopen.rest.sdk.CCPRestSmsSDK;
import com.cpe.data.domain.member.Member;
import com.cpe.repository.mapper.member.MemberMapper;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@Transactional
public class AccountService {
	// 验证码失效时间：2分钟
	private final static String EXPIRE_MIN = "2";

	@Resource
	private Environment environment;

	@Resource
	private MemberMapper memberMapper;

	// 将手机-"验证码,时间戳"存储在缓存中（2分钟失效）
	private static Cache<String, Object[]> checkCodeCache = CacheBuilder.newBuilder().maximumSize(10000)
			.expireAfterWrite(2, TimeUnit.MINUTES).build();

	/**
	 * 发送短信验证码
	 * 
	 * @param mobile
	 */
	public String getCheckCode(String mobile) throws Exception {
		String host = environment.getProperty("yuntongxun.host");
		String port = environment.getProperty("yuntongxun.port");
		String accountSid = environment.getProperty("yuntongxun.account.sid");
		String authToken = environment.getProperty("yuntongxun.auth.token");
		String appid = environment.getProperty("yuntongxun.appid");
		String tmpl = environment.getProperty("yuntongxun.checkcode.tmpl");
		// 随机生成4位数的验证码
		String checkCode = RandomUtils.nextInt(1000, 10000) + "";
		log.debug("验证码：" + checkCode);

		CCPRestSmsSDK restAPI = new CCPRestSmsSDK();
		restAPI.init(host, port);
		restAPI.setAccount(accountSid, authToken);
		restAPI.setAppId(appid);
		String[] datas = new String[] { checkCode, EXPIRE_MIN };
		Map<String, Object> result = restAPI.sendTemplateSMS(mobile, tmpl, datas);
		if ("000000".equals(result.get("statusCode"))) {
			// 正常返回输出data包体信息（map）
			Map<?, ?> templateSMS = (Map<?, ?>) ((Map<?, ?>) result.get("data")).get("templateSMS");
			String dateCreated = (String) templateSMS.get("dateCreated");
			Long time = new SimpleDateFormat("yyyyMMddHHmmss").parse(dateCreated).getTime();
			checkCodeCache.put(mobile, new Object[] { checkCode, time });
			return checkCode;
		} else {
			// 异常返回输出错误码和错误信息
			String message = "错误码=" + result.get("statusCode") + " 错误信息= " + result.get("statusMsg");
			log.info(message);
			throw new Exception(message);
		}
	}

	/**
	 * 校验验证码是否正确
	 */
	public boolean validateCheckCode(String checkCode, String mobile) {
		Assert.hasText(checkCode);
		Assert.hasText(mobile);
		Object[] objs = checkCodeCache.getIfPresent(mobile);
		if (objs == null) {
			return false;
		}
		String stored = (String) objs[0];
		log.info("checkCode = " + checkCode);
		log.info("stored = " + stored);
		return checkCode.equals(stored);
	}

	/**
	 * 绑定手机号
	 */
	public Member bindMobile(String memberId, String mobile) throws Exception {
		Assert.hasText(memberId);
		Assert.hasText(mobile);
		Member member = memberMapper.findById(memberId);
		if (member != null) {
			member.setMobile(mobile);
			member.setMobileStatus(1);
			memberMapper.updateById(member);
			return member;
		}
		return null;
	}
}
